package thingapi

import (
	"iot-base/common/cache"
	"iot-base/common/dbconn"
	"iot-base/common/dbobj"
	"iot-base/common/webapi"

	"github.com/gin-gonic/gin"
	"gorm.io/datatypes"
	"gorm.io/gorm"
)

func queryTModelProtocolRest(c *gin.Context) bool {
	mid := c.Param("id")
	spec := c.Query("spec")
	var result []dbobj.TModelProtocol
	var err error
	if spec != "" {
		err = dbconn.DBConnection.Where("model_id=? and specification=?", mid, spec).Find(&result).Error
	} else {
		err = dbconn.DBConnection.Where("model_id=?", mid).Find(&result).Error
	}

	if err != nil {
		webapi.SendError("query model params "+err.Error(), webapi.DBError, c)
	} else {
		webapi.SendResult(result, nil, c)
	}
	return true
}

type protocol struct {
	ProtocolPath string         `json:"protocol_path"`
	Param        datatypes.JSON `json:"param"`
}
type modelProtocol struct {
	ModelID       string     `json:"model_id"`
	Protocols     []protocol `json:"protocols"`
	Specification string     `json:"spec"`
}

func removeProtocol(c *gin.Context) bool {
	id := c.Param("id")
	path := c.Query("path")
	spec := c.Query("spec")
	var err error
	if path == "" {
		if spec != "" {
			err = dbconn.DBConnection.Exec("delete from t_model_params where model_id=? and specification = ?", id, spec).Error

		} else {
			err = dbconn.DBConnection.Exec("delete from t_model_params where model_id=? and (specification = '' or specification is null)", id).Error
		}
	} else {
		err = dbconn.DBConnection.Exec("delete from t_model_params where model_id=? and protocol_path=? and specification=?",
			id, path, spec).Error
	}

	if err != nil {
		webapi.SendError("removeProtocol "+err.Error(), webapi.DBError, c)
	} else {
		webapi.SendOK(c)
	}
	return true
}

//更新设备互联协议
func updateProtocol(c *gin.Context) bool {
	var param modelProtocol
	err := c.ShouldBind(&param)
	if err != nil {
		webapi.SendError("update protocol "+err.Error(), webapi.DBError, c)
		return true
	}
	errDB := dbconn.DBConnection.Transaction(func(tx *gorm.DB) error {

		var mparam dbobj.TModelProtocol
		if len(param.Protocols) > 0 {
			for _, v := range param.Protocols {
				mparam.ModelID = param.ModelID
				mparam.ProtocolPath = v.ProtocolPath
				mparam.Param = v.Param
				mparam.Specification = param.Specification
				mparam.UID = 0
				var obj dbobj.TModelProtocol
				err = tx.Where("protocol_path=? and model_id=? and specification=?",
					v.ProtocolPath, param.ModelID, param.Specification).Find(&obj).Error
				if err == nil {
					tx.Where("protocol_path=? and model_id=? and specification=?",
						v.ProtocolPath, param.ModelID, param.Specification).Delete(&dbobj.TModelProtocol{})
				}
				err = tx.Create(&mparam).Error
				if err != nil {
					return err
				}
			}
		}

		// 返回 nil 提交事务
		return nil
	})
	cache.DirtyProtocolByMID(param.ModelID)
	if errDB != nil {
		webapi.SendError("updateProtocol "+errDB.Error(), webapi.DBError, c)
	} else {
		webapi.SendOK(c)
	}
	return true
}

func updateOneProtocol(c *gin.Context) bool {
	var protocol dbobj.TModelProtocol
	err := c.ShouldBind(&protocol)
	if err != nil {
		webapi.SendError("update protocol "+err.Error(), webapi.DBError, c)
		return true
	}
	dbconn.DBConnection.Delete(&dbobj.TModelProtocol{}, "model_id=? and protocol_path=? and specification=?",
		protocol.ModelID, protocol.ProtocolPath, protocol.Specification)
	cache.DirtyProtocol(protocol.ModelID, protocol.ProtocolPath, protocol.Specification)
	err = dbconn.DBConnection.Save(&protocol).Error
	if err != nil {
		webapi.SendError("put protocol "+err.Error(), webapi.DBError, c)
	} else {
		webapi.SendOK(c)
	}
	return true
}
